package com.charles.seckillPlatform.service.impl;

import com.charles.seckillData.domain.SysOrder;
import com.charles.seckillComponentCommon.constants.CacheConstants;
import com.charles.seckillComponentCommon.exceptions.ServiceException;
import com.charles.seckillPlatform.mapper.SysBankMapper;
import com.charles.seckillPlatform.service.BankPayService;
import com.charles.seckillPlatform.service.SysOrderService;
import com.charles.seckillPlatform.vo.BankCardInfo;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author Charles-H
 * 
 * 本地支付业务
 */
@Service
@EnableTransactionManagement
public class BankPayServiceImpl implements BankPayService {
    
    @Autowired
    private SysBankMapper sysBankMapper;

    @Autowired
    private SysOrderService sysOrderService;

    @Autowired
    @Qualifier("myRedisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;
    
    @Transactional(rollbackFor = ServiceException.class)
    public void payOrder(BankCardInfo bankCardInfo, String orderId) {
        RLock lock = redissonClient.getLock("PayOrderByBankCard:" + bankCardInfo.getBankId() + ":" + orderId);

        try {
            boolean locked = lock.tryLock(10, 30, TimeUnit.SECONDS);

            if (locked) {
                SysOrder order = (SysOrder) redisTemplate.opsForValue().get(CacheConstants.ORDER_ID + orderId);

                // 订单状态 2: 已过期
                if (order == null || order.getStatus().equals("2")) {
                    throw new ServiceException("您的订单已过期。");
                }

                // 订单状态 1: 已支付
                if (order.getStatus().equals("1")) {
                    throw new ServiceException("您的订单已完成支付。");
                }

                BigDecimal payPrices = Optional.ofNullable(order.getSeckill_price())
                        .orElse(order.getPrice());

                // 判断余额，如果余额够就支付，不够就报错
                if (bankCardInfo.getCardBalance().compareTo(payPrices) < 0) {
                    throw new ServiceException("您的银行卡余额不足。");
                }

                sysBankMapper.modifyBankBalance(bankCardInfo.getBankId(), bankCardInfo.getCardBalance().subtract(payPrices));

                // payWay: 1 本地支付
                sysOrderService.payOrderSuccess(orderId, "1");
            } else {
                throw new ServiceException("抱歉，当前服务器人数过多，请稍后再试");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new ServiceException("抱歉，服务端异常，请稍后再试");
        } finally {
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
    


}
